Skip to content

Conversation

@ymc9
Copy link
Member

@ymc9 ymc9 commented Aug 20, 2025

Summary by CodeRabbit

  • New Features
    • Computed field resolvers now receive a context with currentModel for dynamic references.
    • Optional client logging enabled via log: ['query'].
  • Bug Fixes
    • More reliable queries in complex/self-relations by preventing alias collisions.
    • Deterministic ordering for many-to-many joins.
  • Documentation
    • README example updated for computed field filtering.
  • Tests
    • Relation tests reorganized and expanded: one-to-one, one-to-many, many-to-many, and self-relations.
  • Chores
    • Version bump across packages to 3.0.0-alpha.29.

Copilot AI review requested due to automatic review settings August 20, 2025 09:02
@coderabbitai
Copy link

coderabbitai bot commented Aug 20, 2025

Walkthrough

Introduces alias-aware query building across runtime dialects and operations, updates computed-field invocation to accept a context with currentModel, revises many-to-many FK ordering, restructures relation tests into granular suites, updates samples and README accordingly, and performs version bumps across packages. No exported API types changed except internal dialect method signatures.

Changes

Cohort / File(s) Summary of changes
Version bumps
package.json, packages/*/package.json, samples/blog/package.json, tests/e2e/package.json
Increment versions from 3.0.0-alpha.28 to 3.0.0-alpha.29; no functional changes.
Runtime CRUD dialect aliasing
packages/runtime/src/client/crud/dialects/base.ts, .../dialects/postgresql.ts, .../dialects/sqlite.ts
Add pervasive model aliasing to select/join/filter/order/pagination; introduce/propagate subquery aliases; adjust relation JSON building to use aliases; update multiple method signatures to accept modelAlias.
Runtime operations updates
packages/runtime/src/client/crud/operations/aggregate.ts, .../operations/base.ts, .../operations/count.ts
Pass alias arguments to dialect methods; add deterministic sort for m2m join handling; align usages with new signatures.
Query utilities
packages/runtime/src/client/query-utils.ts
Computed fields now receive context { currentModel }; rework many-to-many FK ordering for deterministic behavior and self-relations.
Relation tests restructuring
packages/runtime/test/client-api/relation.test.ts (removed), packages/runtime/test/client-api/relation/*.test.ts
Remove monolithic relation test; add focused suites for one-to-one, one-to-many, many-to-many, and self-relations across sqlite/postgresql.
Computed fields test
packages/runtime/test/client-api/computed-fields.test.ts
Update computed field resolver to (eb, context) and use sql.ref with context.currentModel.
SDK generator
packages/sdk/src/ts-schema-generator.ts
Generated computed-field methods accept first parameter _context: { currentModel: string }.
Samples update
samples/blog/main.ts, samples/blog/zenstack/schema.ts
Computed field accepts context and uses sql.ref; enable client log: ['query']; adjust schema computed field signature.
README
README.md
Update example subquery whereRef from 'User.id' to 'id'.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

A nibble of alias, a hop through a join,
I twitch my whiskers at models conjoined.
With context in paw and subqueries neat,
I count all the posts—what a tasty treat! 🥕
Relations untangled, tests multiply—
Thump-thump: shipped with a rabbit’s eye.

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch dev

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@claude
Copy link

claude bot commented Aug 20, 2025

Claude finished @ymc9's task —— View job


PR Review: Merge dev to main

I've completed a comprehensive review of this pull request that merges the dev branch to main. This PR contains significant improvements to the runtime engine, particularly around self-relation support and test organization.

Todo List:

  • Analyze version bumps and package.json changes
  • Review runtime dialect implementations (base, postgresql, sqlite)
  • Examine query operation changes
  • Review test reorganization and new self-relation tests
  • Check schema generator changes
  • Assess overall code quality and potential issues
  • Provide comprehensive feedback

Key Changes Summary

This PR introduces self-relation support and significantly improves the codebase organization:

✅ Positive Changes

  1. Self-Relation Support Implementation

    • Added comprehensive self-relation handling in packages/runtime/src/client/crud/dialects/base.ts:485-495
    • Proper many-to-many join table field ordering using model and field name sorting
    • Handles complex cases like self-referential User-to-User relationships
  2. Test Organization & Coverage

    • Excellent refactor: Split monolithic relation.test.ts (762 lines) into focused test files:
      • many-to-many.test.ts (603 lines)
      • one-to-many.test.ts (98 lines)
      • one-to-one.test.ts (92 lines)
      • self-relation.test.ts (757 lines)
    • Added comprehensive self-relation tests covering one-to-one, one-to-many, and many-to-many scenarios
  3. Version Management

    • Clean version bump to 3.0.0-alpha.29 across all packages
    • Consistent versioning strategy maintained
  4. Runtime Engine Improvements

    • Enhanced query building logic in base.ts and dialect-specific implementations
    • Better handling of delegate model relationships
    • Improved many-to-many relationship management with proper FK ordering

🔍 Code Quality Assessment

Strengths:

  • Excellent architecture: Self-relation logic properly handles edge cases
  • Well-structured: The field/model name sorting in M2M relations prevents ambiguity
  • Comprehensive testing: New self-relation tests cover complex scenarios including nested creates, connects, and disconnects
  • Clean separation: Test file reorganization improves maintainability

Areas for Improvement:

  • Complex logic: The self-relation handling in handleManyToManyRelation (lines 485-495) is sophisticated but could benefit from inline comments explaining the sorting logic
  • Type safety: Some any types remain in relation handling code that could be made more specific

🚀 Performance & Security

Performance:

  • ✅ Query building optimizations maintained
  • ✅ Proper use of Kysely query builder patterns
  • ✅ No obvious N+1 query issues introduced

Security:

  • ✅ No hardcoded secrets or credentials
  • ✅ SQL injection protection through Kysely's parameterized queries
  • ✅ Input validation patterns maintained

🧪 Test Coverage

Excellent test additions:

  • Self-relation tests cover all major use cases
  • Tests include both SQLite and PostgreSQL providers
  • Edge cases like disconnection and nested operations are covered
  • Test organization significantly improved for maintainability

Overall Assessment

This is a high-quality PR that introduces important self-relation functionality while improving code organization. The self-relation implementation is well-thought-out and handles complex scenarios properly. The test reorganization is exemplary and will significantly improve developer experience.

Recommendation: ✅ APPROVE

The changes are well-implemented, thoroughly tested, and represent a meaningful improvement to the codebase. The self-relation feature is a valuable addition that maintains consistency with the existing architecture.

Minor Suggestions (Non-blocking)

  1. Consider adding inline comments in handleManyToManyRelation explaining the sorting logic for self-relations
  2. The complex relation handling logic in base.ts could benefit from additional unit tests for edge cases

@ymc9 ymc9 changed the title merge dev to main merge dev to main (v3.0.0-alpha.29) Aug 20, 2025
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR merges the dev branch to main, bumping the version from 3.0.0-alpha.28 to 3.0.0-alpha.29. The primary purpose is to update computed fields to support a context parameter with the current model name, enabling more flexible reference handling in database queries.

Key changes include:

  • Updated computed field signatures to accept a context parameter containing the current model name
  • Enhanced self-relation handling in many-to-many join table foreign key ordering
  • Reorganized relation tests into separate files for better maintainability

Reviewed Changes

Copilot reviewed 34 out of 34 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
Multiple package.json files Version bump from alpha.28 to alpha.29
packages/sdk/src/ts-schema-generator.ts Adds context parameter to computed field method signatures
samples/blog/ files Updates computed field usage to use new context parameter
packages/runtime/ files Implements context parameter support and fixes self-relation handling
packages/runtime/test/client-api/relation/ Reorganizes relation tests into separate files by type

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/runtime/src/client/crud/dialects/postgresql.ts (1)

242-249: Fix missing alias in payload.select branch for scalar fields

In the payload.select branch of
packages/runtime/src/client/crud/dialects/postgresql.ts
the call to this.fieldRef is dropping the relation alias:

• At line 247, change:

- this.fieldRef(relationModel, field, eb, undefined, false);
+ this.fieldRef(relationModel, field, eb, relationModelAlias, false);

A quick grep confirms this is the only occurrence of this.fieldRef(..., undefined, false) in this file.

packages/runtime/src/client/crud/dialects/sqlite.ts (1)

151-156: Add subquery alias in scalar field selections

Both calls to fieldRef in packages/runtime/src/client/crud/dialects/sqlite.ts currently pass undefined for the alias, which can lead to ambiguous column references and breaks computed fields. Update them to use subQueryName:

• packages/runtime/src/client/crud/dialects/sqlite.ts:154
• packages/runtime/src/client/crud/dialects/sqlite.ts:185

Suggested diff:

--- a/packages/runtime/src/client/crud/dialects/sqlite.ts
+++ b/packages/runtime/src/client/crud/dialects/sqlite.ts
@@ 151,7  # “select all scalar fields” branch
- .map(([field]) => [sql.lit(field), this.fieldRef(relationModel, field, eb, undefined, false)])
+ .map(([field]) => [sql.lit(field), this.fieldRef(relationModel, field, eb, subQueryName, false)])
@@ 183,7  # “select specific fields” branch
-     return [
-         sql.lit(field),
-         this.fieldRef(relationModel, field, eb, undefined, false) as ArgsType,
-     ];
+     return [
+         sql.lit(field),
+         this.fieldRef(relationModel, field, eb, subQueryName, false) as ArgsType,
+     ];

This ensures each column reference is correctly scoped to the subquery alias.

🧹 Nitpick comments (13)
packages/cli/package.json (1)

6-6: CLI package version bump LGTM

Consider updating release notes/changelog to reflect the new pre-release if you haven’t already.

packages/sdk/src/ts-schema-generator.ts (1)

355-372: Optional: extract a reusable context type to avoid inline duplication

Instead of emitting an inline type literal for every computed field method, consider reusing a named type (e.g., ComputedFieldContext) from @zenstackhq/runtime/schema if available, or emit a local type alias once per file. This reduces duplication and eases future evolution of the context shape.

packages/runtime/test/client-api/computed-fields.test.ts (1)

240-245: Nit: Destructure context and align alias to the field name to reduce coupling

  • Destructure currentModel directly for brevity.
  • Alias the count as postCount to avoid relying on downstream alias remapping. It makes the intent self-evident and resilient to future changes.
-                            postCount: (eb: any, context: { currentModel: string }) =>
+                            postCount: (eb: any, { currentModel }: { currentModel: string }) =>
                                 eb
                                     .selectFrom('Post')
-                                    .whereRef('Post.authorId', '=', sql.ref(`${context.currentModel}.id`))
-                                    .select(() => eb.fn.countAll().as('count')),
+                                    .whereRef('Post.authorId', '=', sql.ref(`${currentModel}.id`))
+                                    .select(() => eb.fn.countAll().as('postCount')),
samples/blog/main.ts (1)

9-9: Guard verbose query logging for samples

Consider enabling query logging conditionally so sample users don’t flood output unintentionally.

-        log: ['query'],
+        // Enable with: DEBUG=1 node main.js
+        log: process.env.DEBUG ? ['query'] : undefined,
packages/runtime/test/client-api/relation/one-to-many.test.ts (1)

78-96: Optional: add coverage for filtered includes and ordering

To further validate alias-aware query building, consider adding:

  • include with where/orderBy on posts1/posts2
  • filtering User by conditions on each relation independently
packages/runtime/test/client-api/relation/one-to-one.test.ts (1)

51-90: Optional: add negative-path validations

Consider extending with:

  • attempting to create a second profile on the same named relation to hit the unique constraint
  • connect/disconnect flows for 1-1 to ensure aliasing holds for updates too
packages/runtime/test/client-api/relation/many-to-many.test.ts (2)

388-396: Direct join-table inspection: fragile but effective

Checking _TagToUser/_${relationName} via $qbRaw is a strong assertion. Be aware that:

  • The A/B column mapping is provider/implementation-defined; if Prisma or the dialect changes naming, this may break.
  • If you want to reduce brittleness, consider asserting via high-level API only, or gate this check per provider/version.

84-113: Optional: isolate sqlite DB names to avoid file lock races

Vitest generally runs tests in a file sequentially, but if concurrency is enabled later, both relationName variants could contend on ./test.db (sqlite). Using distinct dbNames per variant avoids potential locking issues.

Example:

  • dbName: relationName ? ${TEST_DB}-named : ${TEST_DB}-unnamed
packages/runtime/src/client/crud/operations/aggregate.ts (1)

66-66: Nit: consider using a named subquery alias constant for consistency

CountOperationHandler uses a subQueryName constant. Here the '$sub' alias is hardcoded in multiple places (e.g., Line 66; later: sql.ref($sub.${field}) Lines 84/106). Defining a local const subQueryName = '$sub' would improve consistency and reduce typos.

packages/runtime/src/client/crud/operations/count.ts (1)

15-36: Minor consistency suggestion: reuse subQueryName everywhere

You already use const subQueryName = '$sub'. If there are any future references to the alias (e.g., in added projections), keep using this constant to avoid divergent literals.

packages/runtime/src/client/query-utils.ts (1)

181-182: Computed-field now receives context: tighten typing and clarify naming

Good call passing { currentModel: modelAlias }. Two suggestions:

  • Add a strict function type for computed fields so callers get compile-time help.
  • Consider renaming currentModel to currentAlias to avoid conflating model name vs. table alias.

Example type to add next to ClientOptions:

export type ComputedFieldFn = (
  eb: ExpressionBuilder<any, any>,
  ctx: { currentModel?: string }
) => ExpressionWrapper<any, any, unknown>;

And use it to type computedFields lookup instead of Function.

packages/runtime/test/client-api/relation/self-relation.test.ts (1)

15-31: Stabilize test DB isolation: give each test a unique dbName and consistently force-reset schema

Reusing the same dbName across multiple tests and mixing usePrismaPush true/false can cause cross-test contamination (especially for sqlite) and Postgres flakiness when the DB is not pre-created. Use unique db names per test and prefer usePrismaPush: true everywhere for deterministic resets.

Apply these diffs for each test’s client creation:

@@
-                {
-                    provider,
-                    dbName: TEST_DB,
-                    usePrismaPush: true,
-                },
+                {
+                    provider,
+                    dbName: `${TEST_DB}-${provider}-o2o`,
+                    usePrismaPush: true,
+                },
@@
-                {
-                    provider,
-                    dbName: TEST_DB,
-                    usePrismaPush: true,
-                },
+                {
+                    provider,
+                    dbName: `${TEST_DB}-${provider}-o2m`,
+                    usePrismaPush: true,
+                },
@@
-                {
-                    provider,
-                    dbName: provider === 'postgresql' ? TEST_DB : undefined,
-                    usePrismaPush: true,
-                },
+                {
+                    provider,
+                    dbName: `${TEST_DB}-${provider}-m2m`,
+                    usePrismaPush: true,
+                },
@@
-                {
-                    provider,
-                    dbName: TEST_DB,
-                },
+                {
+                    provider,
+                    dbName: `${TEST_DB}-${provider}-explicit-m2m`,
+                    usePrismaPush: true,
+                },
@@
-                {
-                    provider,
-                    usePrismaPush: true,
-                    dbName: TEST_DB,
-                },
+                {
+                    provider,
+                    dbName: `${TEST_DB}-${provider}-multi-self`,
+                    usePrismaPush: true,
+                },
@@
-                {
-                    provider,
-                    usePrismaPush: true,
-                    dbName: TEST_DB,
-                },
+                {
+                    provider,
+                    dbName: `${TEST_DB}-${provider}-deep`,
+                    usePrismaPush: true,
+                },

Verification suggested:

  • For Postgres, confirm the database creation path is reliable when usePrismaPush: true. If Prisma doesn't create the DB, consider flipping to usePrismaPush: false for Postgres (letting createTestClient precreate the DB), or precreate DBs in test bootstrap.

Also applies to: 122-138, 305-321, 528-552, 604-624, 674-690

packages/runtime/src/client/crud/dialects/base.ts (1)

892-917: Reduce alias collision risk when ordering by to-one relations

Left-joining the relation table without a unique alias can collide if multiple relations target the same model or when self-relations are involved. Use a per-field alias.

Apply:

-                        // order by to-one relation
-                        result = result.leftJoin(relationModel, (join) => {
-                            const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationModel);
+                        // order by to-one relation
+                        const relationJoinAlias = `${modelAlias}$orderBy$${field}`;
+                        result = result.leftJoin(`${relationModel} as ${relationJoinAlias}`, (join) => {
+                            const joinPairs = buildJoinPairs(this.schema, model, modelAlias, field, relationJoinAlias);
                             return join.on((eb) =>
                                 this.and(
                                     eb,
                                     ...joinPairs.map(([left, right]) => eb(sql.ref(left), '=', sql.ref(right))),
                                 ),
                             );
                         });
-                        result = this.buildOrderBy(result, fieldDef.type, relationModel, value, false, negated);
+                        result = this.buildOrderBy(result, fieldDef.type, relationJoinAlias, value, false, negated);
📜 Review details

Configuration used: .coderabbit.yaml
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 32691ce and cd6ccb4.

📒 Files selected for processing (34)
  • README.md (1 hunks)
  • package.json (1 hunks)
  • packages/cli/package.json (1 hunks)
  • packages/common-helpers/package.json (1 hunks)
  • packages/create-zenstack/package.json (1 hunks)
  • packages/dialects/sql.js/package.json (1 hunks)
  • packages/eslint-config/package.json (1 hunks)
  • packages/ide/vscode/package.json (1 hunks)
  • packages/language/package.json (1 hunks)
  • packages/runtime/package.json (1 hunks)
  • packages/runtime/src/client/crud/dialects/base.ts (15 hunks)
  • packages/runtime/src/client/crud/dialects/postgresql.ts (7 hunks)
  • packages/runtime/src/client/crud/dialects/sqlite.ts (6 hunks)
  • packages/runtime/src/client/crud/operations/aggregate.ts (1 hunks)
  • packages/runtime/src/client/crud/operations/base.ts (5 hunks)
  • packages/runtime/src/client/crud/operations/count.ts (1 hunks)
  • packages/runtime/src/client/query-utils.ts (2 hunks)
  • packages/runtime/test/client-api/computed-fields.test.ts (2 hunks)
  • packages/runtime/test/client-api/relation.test.ts (0 hunks)
  • packages/runtime/test/client-api/relation/many-to-many.test.ts (1 hunks)
  • packages/runtime/test/client-api/relation/one-to-many.test.ts (1 hunks)
  • packages/runtime/test/client-api/relation/one-to-one.test.ts (1 hunks)
  • packages/runtime/test/client-api/relation/self-relation.test.ts (1 hunks)
  • packages/sdk/package.json (1 hunks)
  • packages/sdk/src/ts-schema-generator.ts (1 hunks)
  • packages/tanstack-query/package.json (1 hunks)
  • packages/testtools/package.json (1 hunks)
  • packages/typescript-config/package.json (1 hunks)
  • packages/vitest-config/package.json (1 hunks)
  • packages/zod/package.json (1 hunks)
  • samples/blog/main.ts (1 hunks)
  • samples/blog/package.json (1 hunks)
  • samples/blog/zenstack/schema.ts (1 hunks)
  • tests/e2e/package.json (1 hunks)
💤 Files with no reviewable changes (1)
  • packages/runtime/test/client-api/relation.test.ts
🧰 Additional context used
📓 Path-based instructions (2)
{packages,samples,tests}/**

📄 CodeRabbit Inference Engine (CLAUDE.md)

Packages are located in packages/, samples/, and tests/

Files:

  • packages/sdk/package.json
  • packages/runtime/package.json
  • packages/language/package.json
  • packages/testtools/package.json
  • packages/runtime/test/client-api/relation/self-relation.test.ts
  • packages/cli/package.json
  • packages/tanstack-query/package.json
  • packages/vitest-config/package.json
  • packages/typescript-config/package.json
  • packages/create-zenstack/package.json
  • packages/ide/vscode/package.json
  • packages/dialects/sql.js/package.json
  • tests/e2e/package.json
  • packages/zod/package.json
  • packages/eslint-config/package.json
  • packages/common-helpers/package.json
  • packages/runtime/test/client-api/relation/many-to-many.test.ts
  • packages/runtime/src/client/query-utils.ts
  • samples/blog/zenstack/schema.ts
  • packages/runtime/test/client-api/relation/one-to-many.test.ts
  • packages/runtime/test/client-api/computed-fields.test.ts
  • samples/blog/package.json
  • packages/runtime/test/client-api/relation/one-to-one.test.ts
  • packages/sdk/src/ts-schema-generator.ts
  • packages/runtime/src/client/crud/operations/count.ts
  • packages/runtime/src/client/crud/dialects/postgresql.ts
  • packages/runtime/src/client/crud/dialects/sqlite.ts
  • packages/runtime/src/client/crud/dialects/base.ts
  • packages/runtime/src/client/crud/operations/aggregate.ts
  • samples/blog/main.ts
  • packages/runtime/src/client/crud/operations/base.ts
tests/e2e/**

📄 CodeRabbit Inference Engine (CLAUDE.md)

E2E tests are in tests/e2e/ directory

Files:

  • tests/e2e/package.json
🧠 Learnings (1)
📚 Learning: 2025-08-04T08:43:33.161Z
Learnt from: CR
PR: zenstackhq/zenstack-v3#0
File: CLAUDE.md:0-0
Timestamp: 2025-08-04T08:43:33.161Z
Learning: `zenstack generate` compiles ZModel to TypeScript schema (`schema.ts`)

Applied to files:

  • packages/language/package.json
🧬 Code Graph Analysis (6)
packages/runtime/test/client-api/relation/self-relation.test.ts (3)
packages/runtime/test/utils.ts (1)
  • createTestClient (78-195)
packages/runtime/src/client/crud/dialects/sqlite.ts (1)
  • provider (26-28)
packages/runtime/src/client/crud/dialects/postgresql.ts (1)
  • provider (26-28)
packages/runtime/test/client-api/relation/many-to-many.test.ts (3)
packages/runtime/test/utils.ts (1)
  • createTestClient (78-195)
packages/runtime/src/client/crud/dialects/sqlite.ts (1)
  • provider (26-28)
packages/runtime/src/client/crud/dialects/postgresql.ts (1)
  • provider (26-28)
packages/runtime/test/client-api/relation/one-to-many.test.ts (1)
packages/runtime/test/utils.ts (1)
  • createTestClient (78-195)
packages/runtime/src/client/crud/dialects/postgresql.ts (2)
packages/runtime/src/client/query-utils.ts (1)
  • buildJoinPairs (197-215)
packages/sdk/src/schema/schema.ts (1)
  • FieldDef (59-74)
packages/runtime/src/client/crud/dialects/base.ts (1)
packages/runtime/src/client/query-utils.ts (7)
  • requireModel (20-26)
  • makeDefaultOrderBy (217-220)
  • ensureArray (286-292)
  • getManyToManyRelation (222-258)
  • getIdFields (41-44)
  • buildJoinPairs (197-215)
  • getDelegateDescendantModels (322-335)
samples/blog/main.ts (2)
samples/blog/zenstack/schema.ts (1)
  • schema (9-230)
packages/runtime/src/client/functions.ts (1)
  • currentModel (102-113)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: claude-review
  • GitHub Check: build-test (20.x)
🔇 Additional comments (51)
packages/sdk/package.json (1)

3-3: Version bump to 3.0.0-alpha.29 looks good

No export or dependency changes here; aligns with the repo-wide bump.

packages/runtime/package.json (1)

3-3: Runtime version bump approved — monorepo versions and dependency ranges are consistent

  • Verified all @zenstackhq/* packages share version 3.0.0-alpha.29
  • Confirmed every internal dependency uses workspace:* ranges

All checks passed; good to merge.

packages/language/package.json (1)

4-4: Language package version bump approved

Matches the monorepo update; no export surface changes here.

packages/vitest-config/package.json (1)

4-4: Vitest config version bump looks good

No changes to exports; downstream packages should resolve the new version via workspace.

package.json (1)

3-3: Version bump to 3.0.0-alpha.29 verified across the monorepo

  • No remaining 3.0.0-alpha.28 occurrences found
  • All version fields in every package.json are set to 3.0.0-alpha.29
  • packageManager: "[email protected]" is correctly pinned in root package.json and packages/ide/vscode/package.json
packages/ide/vscode/package.json (1)

4-4: VS Code extension version bump LGTM.

Pre-release publish scripts already use --pre-release; no further changes needed here.

packages/zod/package.json (1)

3-3: Zod package version bump is consistent with the monorepo.

No API or dependency changes implicated; safe to ship.

packages/testtools/package.json (1)

3-3: Testtools package version bump looks good.

No changes to deps or exports; aligns with workspace:* consumers.

packages/typescript-config/package.json (1)

3-3: Typescript-config version bump confirmed.

No functional impact; consistent with repo-wide update.

packages/eslint-config/package.json (1)

3-3: Version bump looks good

Metadata-only change to 3.0.0-alpha.29. No concerns.

samples/blog/package.json (1)

3-3: Sample package version bump LGTM

Aligned to 3.0.0-alpha.29; dependencies remain workspace-pinned. No issues.

packages/common-helpers/package.json (1)

3-3: LGTM: metadata-only version bump

Version advanced to 3.0.0-alpha.29; no functional changes. Good to go.

packages/create-zenstack/package.json (1)

3-3: LGTM: version bump

Bumped to 3.0.0-alpha.29; no other changes. Looks good.

tests/e2e/package.json (2)

3-3: LGTM: version bump to alpha.29

Change is scoped to the version field; no other metadata altered. Looks good.


3-3: All clear: no 3.0.0-alpha.28 remains in the repo
Ran a repo-wide search and all package.json files report version 3.0.0-alpha.29. You’re good to merge.

packages/tanstack-query/package.json (2)

3-3: LGTM: version bumped to alpha.29

No changes to exports, deps, or peerDeps. Safe metadata update.


7-7: Confirm @zenstackhq/tanstack-query’s privacy status

I’ve scanned all 16 package.json files in the repo. The only packages marked "private": true (and with no publishConfig overrides) are:

  • packages/eslint-config
  • packages/ide/vscode
  • packages/typescript-config
  • packages/vitest-config
  • packages/zod
  • tests/e2e
  • packages/tanstack-query

If @zenstackhq/tanstack-query is meant to remain an internal‐only package, no further changes are required. If you intend to publish it in the future, you’ll need to:

  • Remove "private": true
  • (Optionally) Add a publishConfig block in its package.json
  • Ensure this change is incorporated into your release workflow

Please confirm your intended visibility for this package.

packages/dialects/sql.js/package.json (2)

3-3: LGTM: version bumped to alpha.29

No functional changes in scripts/exports/peerDeps. Looks good.


38-41: PeerDependency alignment confirmed
Verified that in packages/dialects/sql.js/package.json (lines 35–41), both dependencies and peerDependencies specify sql.js: ^1.13.0 and kysely: catalog:. The ranges are consistent—no changes needed.

packages/sdk/src/ts-schema-generator.ts (1)

355-372: ComputedFields stub signature change is compatible with SchemaDef and client runtime

The generated methods now take only a { currentModel: string } parameter, but:

  • SchemaDef’s computedFields?: Record<string, Function> places no constraints on parameter shape, so stub functions satisfy satisfies SchemaDef.
  • Runtime client‐side resolvers aren’t using these stubs—they use the user-provided functions typed via ComputedFieldsOptions, which prepend the ExpressionBuilder argument internally.
  • Existing tests and samples continue to call user-supplied computed field functions as (eb, context) ⇒ …, so there’s no signature mismatch at runtime.

No changes required here.

samples/blog/zenstack/schema.ts (1)

78-81: LGTM: computed field now takes context with currentModel

Generated signature postCount(_context: { currentModel: string }): OperandExpression<number> matches the SDK change and enforces passing context at call sites.

packages/runtime/test/client-api/computed-fields.test.ts (1)

1-1: Importing sql for alias-aware refs is correct

This aligns the test with the new computed-field pattern using sql.ref. Looks good.

samples/blog/main.ts (2)

3-3: Correct: bring in sql and SqliteDialect

Required for the dynamic currentModel ref and sample setup. All good.


12-16: Computed field correctly uses currentModel context

Using sql.ref(\${currentModel}.id`)ensures the join condition stays correct under aliasing. The explicit.as('postCount')` keeps the projection stable.

packages/runtime/test/client-api/relation/one-to-many.test.ts (3)

11-13: Good resource cleanup

Disconnecting the client after each test prevents handle leaks across providers.


18-30: Schema for unnamed one-to-many is correct

The directional relation and FK are defined properly; nested create + include assertions below exercise the path well.


56-71: Named one-to-many relations are modeled correctly

Dual relations with distinct relation names and separate FK fields avoid ambiguity and exercise aliasing changes.

packages/runtime/test/client-api/relation/one-to-one.test.ts (2)

18-30: Unnamed one-to-one schema is sound

Single-owner side with @unique FK is correct; the nested write and include assertions verify the end-to-end flow.


54-69: Named one-to-one relations are correctly disambiguated

Separate FKs and relation names ensure unambiguous joins. The test validates both branches in one operation.

packages/runtime/test/client-api/relation/many-to-many.test.ts (6)

15-38: Explicit M2M join-table modeling looks correct

The schema uses an explicit join table with a composite unique across (userId, tagId). The subsequent includes validate both directions.


81-113: Set up for implicit M2M across relationName variants is robust

Using describe.each to exercise both unnamed and named implicit M2M is great. usePrismaPush: true with --force-reset ensures clean state per test.


168-176: Filter-by-related scenarios cover some and none

These assertions are valuable to catch alias or subquery mistakes in the new dialect changes.


331-359: Idempotent connect is verified

Asserting that connecting an already-connected record is a no-op helps guard against duplicate join rows.


446-472: updateMany path validates scoped filtering

Good to see the filter excludes id=2 and updates others; this commonly regresses under alias/subquery rewrites.


524-558: Delete vs deleteMany behaviors are well distinguished

  • delete removes the related Tag entity (not just unlink), as asserted for id=2.
  • deleteMany scoped to the current relation removes only connected targets; Tag(3) gone, Tag(1) remains since it’s not connected at that time. Nice coverage.
packages/runtime/src/client/crud/operations/aggregate.ts (1)

19-23: buildSelectModel signature usage verified — all calls include the root alias

All buildSelectModel call sites across operations and dialects have been updated to pass three arguments, and the base implementation in packages/runtime/src/client/crud/dialects/base.ts declares the new (eb, model, modelAlias) signature. No lingering two-arg calls or mismatched definitions were found.

packages/runtime/src/client/crud/operations/count.ts (1)

18-21: Root alias propagation to buildSelectModel looks good

Passing the third parameter aligns Count with the broader alias-aware changes. No functional concerns here.

packages/runtime/src/client/query-utils.ts (1)

235-245: Many-to-many FK ordering change: deterministic and symmetric — LGTM

Switching to field-name ordering for self-relations removes ambiguity and keeps symmetry across both sides. Join-table naming remains consistent with Prisma conventions. Looks good.

If not already covered, please add/confirm tests for:

  • Self-relation M:N with both sides selected to assert A/B stability.
  • Cross-model M:N asserting A/B assignment lines up with join-table columns.

Also applies to: 247-251

packages/runtime/src/client/crud/dialects/postgresql.ts (3)

86-101: Subquery aliasing for relations: solid isolation

Introducing subQueryAlias and passing it through buildSelectModel, buildSelectAllFields, and buildFilterSortTake will prevent alias collisions (notably self-relations). Well done.


115-129: Join conditions correctly reference the inner alias

Using eb.ref(\${subQueryAlias}.${relationIds[0]}`)in M2M and passingsubQueryAliastobuildJoinPairs` for non-M2M ensures correct scoping. This resolves typical self-join alias conflicts.


221-224: Alias-aware scalar selection (select-all path) is correct

Passing relationModelAlias through fieldRef retains alias context for both plain and computed fields.

packages/runtime/src/client/crud/dialects/sqlite.ts (2)

79-94: Subquery aliasing propagation is correct

Defining subQueryAlias and threading it through select/filter/sort/take prevents alias clashes in self-relations. Good alignment with the Postgres approach.


164-176: Count and nested relation JSON calls updated to direct relation model — LGTM

Dropping unnecessary type assertions and consistently using the relation model improves readability without changing semantics.

packages/runtime/test/client-api/relation/self-relation.test.ts (1)

6-14: Ensure Postgres databases exist when using usePrismaPush: true

createTestClient only drop/creates Postgres DBs when usePrismaPush is false. With usePrismaPush: true, Prisma may not create the database if missing. Make sure test setup pre-creates the DB or use usePrismaPush: false for Postgres runs to rely on the helper’s DB creation.

If your CI does not precreate DBs, flip Postgres tests to usePrismaPush: false or add a pre-step to create ${TEST_DB}-postgresql-* databases before tests.

packages/runtime/src/client/crud/operations/base.ts (3)

147-151: Alias propagation in read-path is solid

Passing model as modelAlias into buildSelectModel, buildFilterSortTake, and buildSelectAllFields aligns with the dialect’s new alias-aware API and prevents collisions in self-joins.

Also applies to: 159-160


487-492: Correct m2m FK ordering for self-relations

Sorting by model name and then field name for identical models matches Prisma’s convention for A/B ordering and fixes ambiguous self-m2m mapping.


1289-1294: ✅ Verified alias-aware subselects for updateMany/delete fallbacks

All call sites of buildSelectModel, buildFilterSortTake, and buildSelectAllFields have been updated to the new signature and aliasing conventions:

• packages/runtime/src/client/crud/operations/base.ts (lines 1289–1294, 1993–1997)
• packages/runtime/src/client/crud/operations/aggregate.ts
• packages/runtime/src/client/crud/operations/count.ts
• packages/runtime/src/client/crud/dialects/base.ts
• packages/runtime/src/client/crud/dialects/sqlite.ts
• packages/runtime/src/client/crud/dialects/postgresql.ts

No outdated usages remain.

packages/runtime/src/client/crud/dialects/base.ts (4)

50-57: Good: root table aliasing and delegate-base joins

buildSelectModel now cleanly aliases the root table and joins delegate bases using thisModelAlias, preventing ambiguous refs in multi-join scenarios.


170-203: Cursor subquery isolation is correct

Introducing subQueryAlias and building the cursor filter against the inner alias prevents alias collisions and produces stable pagination semantics.


925-942: Alias-aware field selection across base and delegate descendants looks good

Forwarding modelAlias through buildSelectAllFields and buildDelegateJoin maintains consistency and prevents ambiguous column refs.

Also applies to: 947-961


984-999: Delegate join signature change is clear and consistent

Joining on id fields using thisModelAlias and otherModelAlias matches the rest of the aliasing strategy.

@ymc9 ymc9 enabled auto-merge August 20, 2025 09:14
@ymc9 ymc9 added this pull request to the merge queue Aug 20, 2025
Merged via the queue into main with commit 23c58bd Aug 20, 2025
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants